/**
 *
 */
package com.angel.common.helpers;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

/** The <code>CollectionHelper.class</code> helps you to manage some collections functions.
 *  All its methods are statics.
 *
 * @author William
 * @version
 */
public class CollectionHelper {

	public static final int[] EMPTY_INTEGER_ARRAY = new int[]{};

	public static final String[] EMPTY_STRING_ARRAY = new String[]{};

	public static final int[] NULL_INTEGER_ARRAY = null;

	public static final String[] NULL_STRING_ARRAY = null;

	/** It is the logger for the class. */
	private static Logger logger = Logger.getLogger(CollectionHelper.class);

	private CollectionHelper(){
		super();
	}

	/** Set current log level.
	 *
	 * @param logLevel
	 */
	public static void setLogLevel(Level logLevel){
		logger.setLevel(logLevel);
	}

	/** Convert a list objects in an array objects.
	 *
	 * @param listObjects
	 * @return an array objects converted.
	 */
	public static Object[] convertTo(List<Object> arrayListObjects){
		return (Object[]) arrayListObjects.toArray(new Object[arrayListObjects.size()]);
	}

	/** Convert an array objects in a list objects.
	 *
	 * @param objects
	 * @return a list objects converted.
	 */
	public static List<?> convertTo(Object[] objects){
		List<Object> arrayListObject = new ArrayList<Object>();
		if(objects != null){
			for(int i = 0; i < objects.length; i++){
				Object object = objects[i];
				arrayListObject.add(object);
			}
		}
		return arrayListObject;
	}

	/** Test if entities array is empty.
	 *
	 * @param entities to test if it is empty.
	 * @return true if entities array is null or entities array length is zero.
	 */
	public static boolean isEmpty(Object[] entities){
		return entities == null || ( entities != null && entities.length == 0);
	}

	/** Test if entities array is not empty.
	 *
	 * @param entities to test if is not empty.
	 * @return true if entities is not null and its length is more than zero.
	 */
	public static boolean isNotEmpty(Object[] entities){
		return !isEmpty(entities);
	}

	/** Test if entities collection is not empty.
	 *
	 * @param entities to test if is not empty.
	 * @return true if entities is not null and its length is more than zero.
	 */
	public static boolean isNotEmpty(Collection<?> entities){
		return entities != null && !isEmpty(entities.toArray());
	}

	/** Test if entities array is not empty.
	 *
	 * @param entities to test if is not empty.
	 * @return true if entities is not null and its length is more than zero.
	 */
	public static boolean isNotEmptyAsArray(Object ...entities){
		return !isEmpty(entities);
	}

	/** Test if entities array has a specific length.
	 *
	 * @param entities to test its length.
	 * @param length to verify if it is equals to entities array length.
	 * @return true it entities array length is equals to length. Otherwise it returns false.
	 */
	public static boolean hasEntities(Object[] entities, Long length){
		return isNotEmpty(entities) && entities.length == length;
	}

	/** Get size from an array entities.
	 *
	 * @param entities to get its size.
	 * @return entities size.
	 */
	public static Integer getSizeFromArray(Object[] entities){
		return isNotEmpty(entities) ? entities.length : 0;
	}

	/** Get size from an entnties collection.
	 *
	 * @param entities collection to get its size.
	 * @return entities collection size.
	 */
	public static Integer getSizeFromCollection(Collection<?> entities){
		return isNotEmpty(entities) ? entities.size() : 0;
	}

	/** Get size from an array entities.
	 *
	 * @param entities to get its size.
	 * @return entities size.
	 */
	public static Integer getSizeFrom(Object... entities){
		return getSizeFromArray(entities);
	}

	/** Add entities size.
	 *
	 * @param entities1 to get its size.
	 * @param entities2 to get its size.
	 * @return add entities1 size and entities2 size.
	 */
	public static Integer sumSize(Object[] entities1, Object[] entities2){
		return getSizeFromArray(entities1) + getSizeFromArray(entities2);
	}

	/** Add entities size and begin size.
	 *
	 * @param entities1 to get its size.
	 * @param entities2 to get its size.
	 * @param beginSize to add to other entities size.
	 * @return add entities1 size, entities2 and begin size.
	 */
	public static Integer sumSize(Object[] entities1, Object[] entities2, Integer beginSize){
		return beginSize + getSizeFromArray(entities1) + getSizeFromArray(entities2);
	}

	public static String[] convertGenericTo(List<String> collection) {
		String[] list = new String[0];
		if(collection != null && collection.size() > 0){
			list = new String[collection.size()];
			for(int i = 0; i < collection.size();i++){
				list[i] = collection.get(i);
			}
		}
		return list;
	}

	public static <T extends Object> List<T> convertGenericTo(T[] applicationContexts) {
		List<T> list = new ArrayList<T>();
		if(applicationContexts != null && applicationContexts.length > 0){
			for(T t: applicationContexts){
				list.add(t);
			}
		}
		return list;
	}

	/**
	 * Union two lists in one new list. First add to this one list "a",and then it add "b".
	 *
	 * @param <T>
	 * @param a list to union.
	 * @param b list to union.
	 * @return a new list as result union a and b.
	 */
	public static <T extends Object> List<T> union(List<T> a, List<T> b) {
		List<T> list = new ArrayList<T>();
		list.addAll(a);
		list.addAll(b);
		return list;
	}
}
